package resolver

import uk.ac.cam.ch.wwmm.oscar3.flow.OscarFlow
import uk.ac.cam.ch.wwmm.oscar3.resolver.NameResolver
import uk.ac.cam.ch.wwmm.ptclib.scixml.SciXMLDocument
import uk.ac.cam.ch.wwmm.ptclib.scixml.TextToSciXML
import nu.xom.*
import org.apache.log4j.Level
import org.apache.log4j.Logger
import types.Hit

/**
 * User: wohlgemuth
 * Date: Feb 1, 2010
 * Time: 10:49:57 PM
 */
class OscarResolver extends AbstractResolver implements Resolveable {

  protected Logger log = Logger.getLogger("Resolver")

  double confidenceLevel = 0.5

  /**
   * sets our confidence level
   */
  OscarResolver(double confidenceLevel) {
    this.confidenceLevel = confidenceLevel
  }

  /**
   * default constructor
   */
  OscarResolver() {

  }

  /**
   * resolves the given hits
   */
  Set<Hit> resolve(String input) {

    //convert our query string
    SciXMLDocument doc = TextToSciXML.textToSciXML(input)

    log.debug "purging the cache"
    //purge our cache
    NameResolver.purgeCache();

    //create a new flow
    OscarFlow oscarFlow = new OscarFlow(doc);
    oscarFlow.processToSAF();

    log.debug "filter results by confidence"
    //we only want nodes which have a confidence over X and ontology ids
    Nodes nodes = oscarFlow.safXML.query("//saf/annot/slot[@name='confidence' and  . > ${confidenceLevel}]/../slot[@name='ontIDs']/..")

    def doc2 = new Document(oscarFlow.safXML);

      try {
        Serializer serializer = new Serializer(System.out, "ISO-8859-1");
        serializer.setIndent(4);
        serializer.setMaxLength(64);
        serializer.write(doc);
      }
      catch (IOException ex) {
        System.err.println(ex);
      }

    //here we save our results
    Set<Hit> result = new HashSet<Hit>()

    log.debug "filter duplicated values"
    //remove duplicates entries
    for (int i = 0; i < nodes.size(); i++) {
      Node annotation = nodes.get(i)
      Hit hit = new Hit()

      hit.type = Hit.OSCAR
      hit.origin = getClass()

      for (int x = 0; x < annotation.getChildCount(); x++) {

        Element current = (Element) annotation.getChild(x)
        Attribute atr = current.getAttribute("name")

        if (atr.getValue().equals("surface")) {
          hit.value = current.getValue()
        }
        else if (atr.getValue().equals("confidence")) {
          hit.confidence = Double.parseDouble(current.getValue())
        }
      }

      if (!result.contains(hit)) {
        result.add(hit)
      }
    }

    return result
  }
}
